package org.convallaria.infrastruct.rg.monitor;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 注册发现监控指标
 * 
 * @author gjh
 * @since 2025-01-27
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RegistryMetrics {
    
    private final MeterRegistry meterRegistry;
    
    // 计数器
    private final Counter serviceDiscoverySuccessCounter;
    private final Counter serviceDiscoveryFailureCounter;
    private final Counter healthCheckSuccessCounter;
    private final Counter healthCheckFailureCounter;
    private final Counter loadBalancerRequestCounter;
    private final Counter loadBalancerFailureCounter;
    
    // 计时器
    private final Timer serviceDiscoveryTimer;
    private final Timer healthCheckTimer;
    private final Timer loadBalancerTimer;
    
    // 仪表
    private final AtomicLong totalServices = new AtomicLong(0);
    private final AtomicLong healthyServices = new AtomicLong(0);
    private final AtomicLong totalInstances = new AtomicLong(0);
    private final AtomicLong healthyInstances = new AtomicLong(0);
    
    // 服务实例计数器
    private final ConcurrentHashMap<String, AtomicLong> serviceInstanceCounters = new ConcurrentHashMap<>();
    
    public RegistryMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // 初始化计数器
        this.serviceDiscoverySuccessCounter = Counter.builder("registry.service.discovery.success")
                .description("服务发现成功次数")
                .register(meterRegistry);
        
        this.serviceDiscoveryFailureCounter = Counter.builder("registry.service.discovery.failure")
                .description("服务发现失败次数")
                .register(meterRegistry);
        
        this.healthCheckSuccessCounter = Counter.builder("registry.health.check.success")
                .description("健康检查成功次数")
                .register(meterRegistry);
        
        this.healthCheckFailureCounter = Counter.builder("registry.health.check.failure")
                .description("健康检查失败次数")
                .register(meterRegistry);
        
        this.loadBalancerRequestCounter = Counter.builder("registry.loadbalancer.request")
                .description("负载均衡请求次数")
                .register(meterRegistry);
        
        this.loadBalancerFailureCounter = Counter.builder("registry.loadbalancer.failure")
                .description("负载均衡失败次数")
                .register(meterRegistry);
        
        // 初始化计时器
        this.serviceDiscoveryTimer = Timer.builder("registry.service.discovery.duration")
                .description("服务发现耗时")
                .register(meterRegistry);
        
        this.healthCheckTimer = Timer.builder("registry.health.check.duration")
                .description("健康检查耗时")
                .register(meterRegistry);
        
        this.loadBalancerTimer = Timer.builder("registry.loadbalancer.duration")
                .description("负载均衡耗时")
                .register(meterRegistry);
        
        // 初始化仪表
        Gauge.builder("registry.services.total", totalServices, AtomicLong::doubleValue)
                .description("总服务数量")
                .register(meterRegistry);
        
        Gauge.builder("registry.services.healthy", healthyServices, AtomicLong::doubleValue)
                .description("健康服务数量")
                .register(meterRegistry);
        
        Gauge.builder("registry.instances.total", totalInstances, AtomicLong::doubleValue)
                .description("总实例数量")
                .register(meterRegistry);
        
        Gauge.builder("registry.instances.healthy", healthyInstances, AtomicLong::doubleValue)
                .description("健康实例数量")
                .register(meterRegistry);
    }
    
    /**
     * 记录服务发现成功
     */
    public void recordServiceDiscoverySuccess(String serviceId) {
        serviceDiscoverySuccessCounter.increment();
        log.debug("服务发现成功: {}", serviceId);
    }
    
    /**
     * 记录服务发现失败
     */
    public void recordServiceDiscoveryFailure(String serviceId, String reason) {
        serviceDiscoveryFailureCounter.increment();
        log.warn("服务发现失败: {} - {}", serviceId, reason);
    }
    
    /**
     * 记录健康检查成功
     */
    public void recordHealthCheckSuccess(String serviceId, String instanceId) {
        healthCheckSuccessCounter.increment();
        log.debug("健康检查成功: {}:{}", serviceId, instanceId);
    }
    
    /**
     * 记录健康检查失败
     */
    public void recordHealthCheckFailure(String serviceId, String instanceId, String reason) {
        healthCheckFailureCounter.increment();
        log.warn("健康检查失败: {}:{} - {}", serviceId, instanceId, reason);
    }
    
    /**
     * 记录负载均衡请求
     */
    public void recordLoadBalancerRequest(String serviceId, String strategy) {
        loadBalancerRequestCounter.increment();
        log.debug("负载均衡请求: {} - {}", serviceId, strategy);
    }
    
    /**
     * 记录负载均衡失败
     */
    public void recordLoadBalancerFailure(String serviceId, String strategy, String reason) {
        loadBalancerFailureCounter.increment();
        log.warn("负载均衡失败: {}:{} - {}", serviceId, strategy, reason);
    }
    
    /**
     * 记录服务发现耗时
     */
    public Timer.Sample startServiceDiscoveryTimer() {
        return Timer.start(meterRegistry);
    }
    
    /**
     * 停止服务发现计时器
     */
    public void stopServiceDiscoveryTimer(Timer.Sample sample, String serviceId) {
        sample.stop(serviceDiscoveryTimer);
    }
    
    /**
     * 记录健康检查耗时
     */
    public Timer.Sample startHealthCheckTimer() {
        return Timer.start(meterRegistry);
    }
    
    /**
     * 停止健康检查计时器
     */
    public void stopHealthCheckTimer(Timer.Sample sample, String serviceId, String instanceId) {
        sample.stop(healthCheckTimer);
    }
    
    /**
     * 记录负载均衡耗时
     */
    public Timer.Sample startLoadBalancerTimer() {
        return Timer.start(meterRegistry);
    }
    
    /**
     * 停止负载均衡计时器
     */
    public void stopLoadBalancerTimer(Timer.Sample sample, String serviceId, String strategy) {
        sample.stop(loadBalancerTimer);
    }
    
    /**
     * 更新服务数量
     */
    public void updateServiceCount(long total, long healthy) {
        totalServices.set(total);
        healthyServices.set(healthy);
        log.debug("更新服务数量: 总数={}, 健康数={}", total, healthy);
    }
    
    /**
     * 更新实例数量
     */
    public void updateInstanceCount(long total, long healthy) {
        totalInstances.set(total);
        healthyInstances.set(healthy);
        log.debug("更新实例数量: 总数={}, 健康数={}", total, healthy);
    }
    
    /**
     * 更新服务实例数量
     */
    public void updateServiceInstanceCount(String serviceId, long count) {
        serviceInstanceCounters.computeIfAbsent(serviceId, k -> new AtomicLong(0)).set(count);
        log.debug("更新服务实例数量: {} = {}", serviceId, count);
    }
    
    /**
     * 获取服务实例数量
     */
    public long getServiceInstanceCount(String serviceId) {
        return serviceInstanceCounters.getOrDefault(serviceId, new AtomicLong(0)).get();
    }
    
    /**
     * 获取总服务数量
     */
    public long getTotalServices() {
        return totalServices.get();
    }
    
    /**
     * 获取健康服务数量
     */
    public long getHealthyServices() {
        return healthyServices.get();
    }
    
    /**
     * 获取总实例数量
     */
    public long getTotalInstances() {
        return totalInstances.get();
    }
    
    /**
     * 获取健康实例数量
     */
    public long getHealthyInstances() {
        return healthyInstances.get();
    }
}